﻿using System.Diagnostics;
using System.Drawing;
using RaytracerLib.MathLib;
using TomanuExtensions;
using RaytracerLib.Layers.Interpolators;
using RaytracerLib.Layers.OverlayCorrectors;

namespace RaytracerLib.Layers
{
    public abstract class ValueArrayBase : ArrayBase
    {
        protected ValueArrayBase(OverlayMethod a_overlayMethod = OverlayMethod.Overlap,
            InterpolationMethod a_interpolationMethod = InterpolationMethod.Bilinear)
            : base(a_overlayMethod, a_interpolationMethod)
        {
        }

        public Bitmap GetBitmap()
        {
            return GetBitmap(new Rectangle(0, 0, Width, Height));
        }

        public Bitmap GetBitmap(Rectangle a_rect)
        {
            ColorArrayFloat dest = new ColorArrayFloat(a_rect.Width, a_rect.Height);

            for (int y = a_rect.Top; y < a_rect.Bottom; y++)
            {
                for (int x = a_rect.Left; x < a_rect.Right; x++)
                    dest.SetValue(x - a_rect.Left, y - a_rect.Top, GetValue(x, y));
            }

            return dest.GetBitmap();
        }

        public override int GetHashCode()
        {
            return base.GetHashCode();
        }

        public bool IsAlmostRelativeEquals(ValueArrayBase a_ar, float a_precision = Constants.COLOR_PRECISION)
        {
            if (Height != a_ar.Height)
                return false;
            if (Width != a_ar.Width)
                return false;

            for (int y = 0; y < Height; y++)
            {
                for (int x = 0; x < Width; x++)
                {
                    if (!GetValue(x, y).IsAlmostRelativeEquals(a_ar.GetValue(x, y), a_precision))
                        return false;
                }
            }

            return true;
        }

        public override ColorFloat GetColor(int a_x, int a_y)
        {
            return new ColorFloat(GetValue(a_x, a_y));
        }

        public override void SetColor(int a_x, int a_y, ColorFloat a_color)
        {
            SetValue(a_x, a_y, a_color.Avg);
        }

        public double this[int a_x, int a_y]
        {
            get
            {
                return GetValue(a_x, a_y);
            }
            set
            {
                SetValue(a_x, a_y, value);
            }
        }

        public override void Fill(ColorFloat a_color)
        {
            Fill(a_color.Avg);
        }
    }
}